
#include <stdint.h>

#if 1
#include "phCryptoSym.h"

/// <summary>
/// External algoAES processing function
/// </summary>
/// <remarks>
/// This function is not included in the sample code and must be provided externally.
/// In some embedded implementations there may be an AES hardware engine available, with associated API calls.
/// Alternatively, there are a number of example software AES implementations available on the internet, for example:
/// https://github.com/kokke/tiny-AES128-C/blob/master/aes.c or https://github.com/bernarpa/PAES/blob/master/aes/common.c
/// </remarks>
void algoAES_process(uint8_t* key, uint8_t keyLength, uint8_t* input, uint8_t* output, uint8_t mode){
	void* crypt = phNfcLib_GetDataParams(PH_COMP_CRYPTORNG);
	phCryptoSym_LoadKeyDirect(crypt, key, PH_CRYPTOSYM_KEY_TYPE_AES128);
	if(mode == 1){
		phCryptoSym_Encrypt(crypt, PH_CRYPTOSYM_CIPHER_MODE_ECB, input, 16, output);
	}
	else{
		phCryptoSym_Decrypt(crypt, PH_CRYPTOSYM_CIPHER_MODE_ECB, input, 16, output);
	}
}

#if 0
#include "Reader/desfire/aes.h"
#include "Reader/desfire/des.h"

void algoAES_process(uint8_t* key, uint8_t keyLength, uint8_t* input, uint8_t* output, uint8_t mode){
	AES_KEY k;
	if(mode == 1){
		AES_set_encrypt_key(key, 8*keyLength, &k);
		AES_encrypt(input, output, &k);
	}
	else{
		AES_set_decrypt_key(key, 8*keyLength, &k);
		AES_decrypt(input, output, &k);
	}
}
#endif 

#if 0
void algoDES_process(uint8_t* key, uint8_t keyLength, uint8_t* input, uint8_t* output, uint8_t mode){
	DES_key_schedule ks1; /* first component of a TDEA key	*/
	DES_key_schedule ks2; /* second component of a TDEA key */
	DES_key_schedule ks3; /* third component of a TDEA key	*/
	uint8_t edata[8];
	
	switch(keyLength){
	case 8:{
		DES_set_key((DES_cblock *)key, &ks1);
	}
	break;
	case 16:{
		DES_set_key((DES_cblock *)key, &ks1);
		DES_set_key((DES_cblock *)(key + 8), &ks2);
	}
	break;
	case 24:{
		DES_set_key((DES_cblock *)key, &ks1);
		DES_set_key((DES_cblock *)(key + 8), &ks2);
		DES_set_key ((DES_cblock *)(key + 16), &ks3);
	}
	break;
	default :{
		return ;
	}
	}

	switch (keyLength) {
	case 8: 					   /* single DES */
	  switch (mode) {
	  case 1:
		DES_ecb_encrypt((DES_cblock *) input, (DES_cblock *) edata, &ks1,
						DES_ENCRYPT);
		break;
	  case 0:
		DES_ecb_encrypt((DES_cblock *) input, (DES_cblock *) edata, &ks1,
						DES_DECRYPT);
		break;
	  }
	  break;
	  
	case 16:					   /* triple DES */
	  switch (mode) {
	  case 1:
		DES_ecb_encrypt((DES_cblock *) input,  (DES_cblock *) edata, &ks1,
						DES_ENCRYPT);
		DES_ecb_encrypt((DES_cblock *) edata, (DES_cblock *) input,	&ks2,
						DES_DECRYPT);
		DES_ecb_encrypt((DES_cblock *) input,  (DES_cblock *) edata, &ks1,
						DES_ENCRYPT);
		break;
	  case 0:
		DES_ecb_encrypt((DES_cblock *) input,  (DES_cblock *) edata, &ks1,
						DES_DECRYPT);
		DES_ecb_encrypt((DES_cblock *) edata, (DES_cblock *) input,	&ks2, 
						DES_ENCRYPT);
		DES_ecb_encrypt((DES_cblock *) input,  (DES_cblock *) edata, &ks1, 
						DES_DECRYPT);
		break;
	  }
	  break;
	  
	case 24:					   /* 3-key triple DES */
	  switch (mode) {
	  case 1:
		DES_ecb_encrypt((DES_cblock *) input,  (DES_cblock *) edata, &ks1,
						DES_ENCRYPT);
		DES_ecb_encrypt((DES_cblock *) edata, (DES_cblock *) input,	&ks2,
						DES_DECRYPT);
		DES_ecb_encrypt((DES_cblock *) input,  (DES_cblock *) edata, &ks3,
						DES_ENCRYPT);
		break;
	  case 0:
		DES_ecb_encrypt((DES_cblock *) input,  (DES_cblock *) edata, &ks3,
						DES_DECRYPT);
		DES_ecb_encrypt((DES_cblock *) edata, (DES_cblock *) input,	&ks2,
						DES_ENCRYPT);
		DES_ecb_encrypt((DES_cblock *) input,  (DES_cblock *) edata, &ks1,
						DES_DECRYPT);
		break;
	  }
	  break;
	  

	}

}
#endif 

#else

#include "Utility/aes.h"


/// <summary>
/// External algoAES processing function
/// </summary>
/// <remarks>
/// This function is not included in the sample code and must be provided externally.
/// In some embedded implementations there may be an AES hardware engine available, with associated API calls.
/// Alternatively, there are a number of example software AES implementations available on the internet, for example:
/// https://github.com/kokke/tiny-AES128-C/blob/master/aes.c or https://github.com/bernarpa/PAES/blob/master/aes/common.c
/// </remarks>
void algoAES_process(uint8_t* key, uint8_t keyLength, uint8_t* input, uint8_t* output, uint8_t mode){
	if(mode == 1){
		AES128_ECB_encrypt(input, key, output);
	}
	else{
		AES128_ECB_decrypt(input, key, output);
	}
}
#endif 


